package com.kcwl.carrier.application.service;

import cn.hutool.core.util.ObjectUtil;
import com.kcwl.carrier.domain.entity.*;
import com.kcwl.carrier.domain.service.*;
import com.kcwl.carrier.infrastructure.enums.*;
import com.kcwl.carrier.infrastructure.exceptions.CarrierUserException;
import com.kcwl.carrier.infrastructure.utils.DateUtil;
import com.kcwl.carrier.interfaces.command.CarrierAddDriverCommand;
import com.kcwl.carrier.interfaces.command.CarrierDriverCommand;
import com.kcwl.carrier.interfaces.command.HandleWaitingCommand;
import com.kcwl.carrier.interfaces.command.IdCommand;
import com.kcwl.carrier.interfaces.dto.*;
import com.kcwl.carrier.interfaces.enums.CarrierInviteStatusEnum;
import com.kcwl.carrier.interfaces.query.*;
import com.kcwl.ddd.application.constants.IdentityTypeEnum;
import com.kcwl.ddd.application.constants.YesNoEnum;
import com.kcwl.ddd.infrastructure.api.ResponseMessage;
import com.kcwl.euc.interfaces.api.IUserBaseService;
import com.kcwl.euc.interfaces.dto.UserInfoDTO;
import com.kcwl.euc.interfaces.query.UserBaseInfoQuery;
import com.kcwl.framework.utils.CollectionUtil;
import com.kcwl.framework.utils.KcBeanConverter;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author lxp
 * @date 2023/1/10 11:33
 * @Description
 */
@Service
public class CarrierDriverApplicationService {

    @Autowired
    CarrierDriverDomainService carrierDriverDomainService;
    @Autowired
    CarrierInfoDomainService carrierInfoDomainService;
    @Autowired
    private VehicleInfoDomainService vehicleInfoDomainService;
    @Autowired
    private VehicleTrailerDomainService vehicleTrailerDomainService;
    @Autowired
    private CarrierMappingDomainService carrierMappingDomainService;
    @Autowired
    private IUserBaseService userBaseService;

    /**
     * 条件查询老板司机关系
     *
     * @param carrierDriverQuery
     * @return
     */
    public List<CarrierDriverDTO> queryCarrierDriver(CarrierDriverQuery carrierDriverQuery) {
        List<CarrierDriverInfo> carrierDriverInfoList =
            carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        return KcBeanConverter.toList(carrierDriverInfoList, CarrierDriverDTO.class);
    }

    /**
     * 修改老板司机关系
     *
     * @param carrierDriverCommand
     */
    public void updateCarrierDriverInfo(CarrierDriverCommand carrierDriverCommand) {
        CarrierDriverInfo carrierDriverInfo = KcBeanConverter.toBean(carrierDriverCommand, CarrierDriverInfo.class);
        carrierDriverDomainService.updateCarrierDriverInfo(carrierDriverInfo);
    }

    /**
     * 新增老板司机关系
     *
     * @param carrierDriverCommand
     */
    public void createCarrierDriver(CarrierDriverCommand carrierDriverCommand) {
        CarrierDriverInfo carrierDriverInfo = KcBeanConverter.toBean(carrierDriverCommand, CarrierDriverInfo.class);
        carrierDriverDomainService.createCarrierDriver(carrierDriverInfo);
    }

    /**
     * 我的车老板信息(车老板和物流公司)
     *
     * @param idQuery
     * @return
     */
    public List<CarrierInfoDTO> queryAllMyCarriers(IdQuery idQuery) {
        // 查询已接受邀请的老板信息
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setDriverId(idQuery.getId());
        carrierDriverQuery.setIsDel(0);
        carrierDriverQuery.setInviteStatusList(Arrays.asList(CarrierDriverInviteStatusEnum.FREE.getCode(),
            CarrierDriverInviteStatusEnum.CARRIER_FREE.getCode()));
        List<CarrierDriverInfo> carrierDriverInfoList =
            carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        if (CollectionUtil.isEmpty(carrierDriverInfoList)) {
            return new ArrayList<>();
        }
        List<Long> carrierIds =
            carrierDriverInfoList.stream().map(CarrierDriverInfo::getUserId).collect(Collectors.toList());
        // 查询司机表并过滤身份
        List<CarrierInfo> carrierInfoList = carrierInfoDomainService.getByIds(carrierIds);
        List<CarrierInfo> result = carrierInfoList.stream().filter(
            carrierInfo -> IdentityTypeEnum.CARRIER_SFLTOP.getSubType()
                .equals(carrierInfo.getIdentityType()) || IdentityTypeEnum.CARRIER_TCOM_MANAGER.getSubType()
                .equals(carrierInfo.getIdentityType())).collect(Collectors.toList());
        return KcBeanConverter.toList(result, CarrierInfoDTO.class);
    }

    /**
     * TMS重新收纳
     *
     * @param carrierDriverCommand
     */
    public void reTakeTmsDriver(CarrierDriverCommand carrierDriverCommand) {
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setDriverId(carrierDriverCommand.getDriverId());
        carrierDriverQuery.setUserId(carrierDriverCommand.getUserId());
        carrierDriverQuery.setIsDel(YesNoEnum.NAY.getValue());
        List<CarrierDriverInfo> driverInfoList = carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        if (CollectionUtil.isEmpty(driverInfoList)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        CarrierDriverInfo carrierDriverInfo = driverInfoList.get(0);
        // 修改为待司机确认
        carrierDriverInfo.setInviteStatus(CarrierDriverInviteStatusEnum.TRANSPORT.getCode());
        carrierDriverDomainService.updateCarrierDriverInfo(carrierDriverInfo);
    }

    /**
     * TMS收纳司机查询
     *
     * @param mixedInfoQuery
     * @return
     */
    public List<TmsDriverInfoDTO> queryTakeTmsDriver(MixedInfoQuery mixedInfoQuery) {
        List<CarrierInfo> carrierInfoList;
        // 根据查询条件返回司机信息
        if (!CollectionUtil.isEmpty(mixedInfoQuery.getMobileList())) {
            carrierInfoList = carrierInfoDomainService.queryByMobile(mixedInfoQuery.getMobileList());
        } else if (!CollectionUtil.isEmpty(mixedInfoQuery.getNameList())) {
            carrierInfoList = carrierInfoDomainService.queryByName(mixedInfoQuery.getNameList());
        } else {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.ILLEGAL_PARAMS);
        }
        if (CollectionUtil.isEmpty(carrierInfoList)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.NO_REGISTER);
        }
        List<TmsDriverInfoDTO> driverInfoDTOList = KcBeanConverter.toList(carrierInfoList, TmsDriverInfoDTO.class);
        // 已经被收纳的司机
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setDriverIdList(
            carrierInfoList.stream().map(CarrierInfo::getId).collect(Collectors.toList()));
        carrierDriverQuery.setIsDel(YesNoEnum.NAY.getValue());
        carrierDriverQuery.setInviteStatusList(Arrays.asList(10, 20));
        List<CarrierDriverInfo> carrierDriverInfoList =
            carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        Map<Long, CarrierDriverInfo> map = carrierDriverInfoList.stream().filter(
                carrierDriverInfo -> carrierDriverInfo.getDriverId() != null && carrierDriverInfo.getUserId() != null)
            .collect(Collectors.toMap(CarrierDriverInfo::getDriverId, carrierDriverInfo -> carrierDriverInfo));
        for (TmsDriverInfoDTO tmsDriverInfoDTO : driverInfoDTOList) {
            CarrierDriverInfo carrierDriverInfo = map.get(tmsDriverInfoDTO.getId());
            if (carrierDriverInfo == null) {
                tmsDriverInfoDTO.setIsTake(TmsIsTakeEnum.TAKE.getCode());
            } else if (carrierDriverInfo.getUserId().equals(mixedInfoQuery.getUserId())) {
                tmsDriverInfoDTO.setIsTake(TmsIsTakeEnum.ALREADY_TAKE.getCode());
            } else {
                tmsDriverInfoDTO.setIsTake(TmsIsTakeEnum.ANOTHER_ONE_TAKE.getCode());
            }
        }
        return driverInfoDTOList;
    }

    /**
     * 收纳司机
     *
     * @param carrierDriverCommand
     */
    @Transactional(rollbackFor = Exception.class)
    public void takeTmsDriver(CarrierDriverCommand carrierDriverCommand) {
        // 校验司机尚未被收纳
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setDriverIdList(carrierDriverCommand.getDriverIdList());
        carrierDriverQuery.setIsDel(YesNoEnum.NAY.getValue());
        List<CarrierDriverInfo> carrierDriverInfoList =
            carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        if (!CollectionUtil.isEmpty(carrierDriverInfoList)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.EXISTS_ALREADY_BIND_DRIVER);
        }
        List<Long> driverIdList = carrierDriverCommand.getDriverIdList();
        List<CarrierInfo> carrierInfoList = carrierInfoDomainService.getByIds(driverIdList);
        long count = carrierInfoList.stream()
            .filter(carrierInfo -> CarrierAuthStatusEnum.PASS.getCode() != carrierInfo.getAuthenticationStatus())
            .count();
        if (count > 0) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.ILLEGAL_AUTH_STATUS);
        }
        carrierDriverInfoList = new ArrayList<>();
        for (Long driverId : carrierDriverCommand.getDriverIdList()) {
            CarrierDriverInfo carrierDriverInfo = new CarrierDriverInfo();
            carrierDriverInfo.setUserId(carrierDriverCommand.getUserId());
            carrierDriverInfo.setIsDel(YesNoEnum.NAY.getValue());
            carrierDriverInfo.setCreateTime(new Date());
            carrierDriverInfo.setUpdateTime(new Date());
            carrierDriverInfo.setDriverId(driverId);
            carrierDriverInfo.setInviteType(1);
            carrierDriverInfo.setInviteStatus(CarrierDriverInviteStatusEnum.FREE.getCode());
            carrierDriverInfoList.add(carrierDriverInfo);
        }
        carrierDriverDomainService.batchCreateCarrierDriver(carrierDriverInfoList);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean carrierAddDriver(CarrierAddDriverCommand command) {
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(command.getDriverId());
        // 校验车主信息
        if (ObjectUtil.isEmpty(carrierInfo)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_IS_NOT_EXISTS);
        }
        // 校验被邀请的司机身份类型
        if (!Objects.equals(carrierInfo.getIdentityType(), IdentityTypeEnum.CARRIER_DRIVER.getSubType())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CHIEF_NOT_INVITED_DRIVER);
        }
        List<CarrierDriverInfo> carrierDriverQuery = getCarrierDriverQuery(command);
        if (!carrierDriverQuery.isEmpty()) {
            CarrierDriverInfo carrierDriverInfo = carrierDriverQuery.get(0);
            // 校验电话号码是否存在
            if (CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode() == carrierDriverInfo.getInviteStatus() || CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 已添加
                throw new CarrierUserException(CarrierUseErrorCodeEnum.MOBILE_EXISTED);
            }
            if (CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_WAIT.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 未添加，等待验证
                throw new CarrierUserException(CarrierUseErrorCodeEnum.WAIT_DRIVER_AGREE);
            }
            if (CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_WAIT.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 未添加，等待验证
                throw new CarrierUserException(CarrierUseErrorCodeEnum.CAROWNER_WAIT);
            }
            if (CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode() == carrierDriverInfo.getInviteStatus() || CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 已删除，重新修改为等待验证状态
                CarrierDriverInfo carrierDriver = new CarrierDriverInfo();
                carrierDriver.setId(carrierDriverInfo.getId());
                carrierDriver.setInviteStatus(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_WAIT.getCode());
                carrierDriver.setInviteType(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode());
                carrierDriver.setCreateTime(new Date());
                carrierDriverDomainService.updateCarrierDriverInfo(carrierDriver);
            }
        } else {
            // 不存在数据，则新增数据
            CarrierDriverInfo ncd = new CarrierDriverInfo();
            Date date = new Date();
            ncd.setUserId(command.getUserId());
            ncd.setDriverId(command.getDriverId());
            ncd.setIsDel(YesNoEnum.NAY.getValue());
            ncd.setInviteType(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode());
            ncd.setInviteStatus(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_WAIT.getCode());
            ncd.setCreateTime(date);
            ncd.setUpdateTime(date);
            carrierDriverDomainService.createCarrierDriver(ncd);
        }

        return Boolean.TRUE;
    }

    private List<CarrierDriverInfo> getCarrierDriverQuery(CarrierAddDriverCommand command) {
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setDriverId(command.getDriverId());
        carrierDriverQuery.setUserId(command.getUserId());
        return carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
    }

    public List<CarrierAndDriverDTO> queryMyDrivers(CarrierAndDriverQuery query) {
        CarrierDriverQuery carrierDriverQuery = new CarrierDriverQuery();
        carrierDriverQuery.setUserId(query.getUserId());
        carrierDriverQuery.setContent(query.getContent());
        if (CarrierInfoEnums.InviteStatus.PASSED.getCode() == query.getInviteStatus()) {
            carrierDriverQuery.setInviteTypes(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode(),
                CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode()));
            carrierDriverQuery.setInviteStatusList(
                Arrays.asList(CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode(),
                    CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode()));
        }
        if (CarrierInfoEnums.InviteStatus.PENDING.getCode() == query.getInviteStatus()) {
            carrierDriverQuery.setInviteTypes(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode()));
            carrierDriverQuery.setInviteStatusList(
                Arrays.asList(CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_WAIT.getCode()));
        }
        if (CarrierInfoEnums.InviteStatus.LIFTED.getCode() == query.getInviteStatus()) {
            carrierDriverQuery.setInviteTypes(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode(),
                CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode()));
            carrierDriverQuery.setInviteStatusList(
                Arrays.asList(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode(),
                    CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode()));
        }
        List<CarrierDriverInfo> list = this.carrierDriverDomainService.queryCarrierDriver(carrierDriverQuery);
        List<CarrierAndDriverDTO> resList = new ArrayList<>();
        if (!list.isEmpty()) {
            resList = KcBeanConverter.toList(list, CarrierAndDriverDTO.class);
            // 扩展司机信息
            List<Long> driverIds = resList.stream().map(CarrierAndDriverDTO::getDriverId).collect(Collectors.toList());
            List<CarrierInfo> carrierInfos = carrierInfoDomainService.getByIds(driverIds);
            Map<Long, CarrierInfo> carrierInfoMap =
                carrierInfos.stream().collect(Collectors.toMap(CarrierInfo::getId, v -> v, (v1, v2) -> v2));
            // 扩展司机头像
            Map<Long, UserInfoDTO> headUrlMap = getLongUserInfoDTOMap(driverIds);
            resList.forEach(a -> {
                a.setName(carrierInfoMap.get(a.getDriverId()).getName());
                a.setMobile(carrierInfoMap.get(a.getDriverId()).getMobile());
                a.setHeadUrl(headUrlMap.get(a.getDriverId()).getAvatar());
                // 扩展车辆挂车信息
                packageExtTDO(a);
            });
        }
        return resList;
    }

    private Map<Long, UserInfoDTO> getLongUserInfoDTOMap(List<Long> driverIds) {
        UserBaseInfoQuery userBaseInfoQuery = new UserBaseInfoQuery();
        userBaseInfoQuery.setIds(driverIds);
        ResponseMessage<List<UserInfoDTO>> responseMessage = userBaseService.getByUserIds(userBaseInfoQuery);
        List<UserInfoDTO> userInfoDTOS = responseMessage.getResult();
        Map<Long, UserInfoDTO> headUrlMap = new HashMap<>();
        if (!userInfoDTOS.isEmpty()) {
            headUrlMap = userInfoDTOS.stream().collect(Collectors.toMap(UserInfoDTO::getId, v -> v, (v1, v2) -> v2));
        }
        return headUrlMap;
    }

    private void packageExtTDO(CarrierAndDriverDTO dto) {
        CarrierMappingQuery carrierMappingQuery = new CarrierMappingQuery();
        carrierMappingQuery.setCarrierId(dto.getUserId());
        carrierMappingQuery.setDriverId(dto.getDriverId());
        List<CarrierMappingInfo> carrierMappingInfos =
            carrierMappingDomainService.queryCarrierMappingInfo(carrierMappingQuery);
        if (!carrierMappingInfos.isEmpty()) {
            dto.setVehicleId(carrierMappingInfos.get(0).getVehicleId());
            VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(dto.getVehicleId());
            dto.setPlateNumber(vehicleInfo.getPlateNumber());
            dto.setVehicleType(vehicleInfo.getVehicleType().intValue());
            if (vehicleInfo.getTrailerId() != null) {
                VehicleTrailerInfo vehicleTrailerInfo = vehicleTrailerDomainService.getById(vehicleInfo.getTrailerId());
                dto.setTrailerPlateNumber(vehicleTrailerInfo.getVehiclePlateNumber());
            }
        }
    }

    public CarrierSimpleDTO searchDrivers(CarrierInfoQuery query) {
        CarrierListQuery carrierListQuery = new CarrierListQuery();
        carrierListQuery.setCancer(YesNoEnum.NAY.getValue());
        carrierListQuery.setMobile(query.getMobile());
        carrierListQuery.setAuthenticationStatus(CarrierInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode());
        carrierListQuery.setIdentityType(IdentityTypeEnum.CARRIER_DRIVER.getSubType());
        List<CarrierInfo> carrierListByParams = carrierInfoDomainService.getCarrierListByParams(carrierListQuery);
        if (carrierListByParams.isEmpty()) {
            return null;
        }
        CarrierSimpleDTO carrierSimpleDTO = KcBeanConverter.toBean(carrierListByParams.get(0), CarrierSimpleDTO.class);
        UserBaseInfoQuery userBaseInfoQuery = new UserBaseInfoQuery();
        userBaseInfoQuery.setId(carrierListByParams.get(0).getId());
        ResponseMessage<UserInfoDTO> responseMessage = userBaseService.queryById(userBaseInfoQuery);
        carrierSimpleDTO.setHeadUrl(responseMessage.getResult().getAvatar());
        return carrierSimpleDTO;
    }

    public Boolean carrierHandleWaiting(HandleWaitingCommand command) {
        CarrierDriverInfo carrierDriverInfo = carrierDriverDomainService.getById(command.getId());
        if (carrierDriverInfo == null) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (Objects.equals(command.getIsAccept(), YesNoEnum.NAY.getValue())) {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode());
        } else {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode());
        }
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean driverAddCarrier(CarrierAddDriverCommand command) {

        List<CarrierDriverInfo> carrierDriverQuery = getCarrierDriverQuery(command);
        if (!carrierDriverQuery.isEmpty()) {
            CarrierDriverInfo carrierDriverInfo = carrierDriverQuery.get(0);
            // 校验司机跟车老板关系是否存在
            if (CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode() == carrierDriverInfo.getInviteStatus() || CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 已添加
                throw new CarrierUserException(CarrierUseErrorCodeEnum.DRIVER_ADDED);
            }
            if (CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_WAIT.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 待车队长确认
                throw new CarrierUserException(CarrierUseErrorCodeEnum.CAROWNER_WAIT);
            }
            if (CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_WAIT.getCode() == carrierDriverInfo.getInviteStatus()) {
                // 待司机确认
                throw new CarrierUserException(CarrierUseErrorCodeEnum.WAIT_DRIVER_AGREE);
            }

            if (CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode() == carrierDriverInfo.getInviteStatus() || CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode() == carrierDriverInfo.getInviteStatus()) {
                //已删除，重新修改为等待验证状态
                CarrierDriverInfo carrierDriver = new CarrierDriverInfo();
                carrierDriver.setId(carrierDriverInfo.getId());
                carrierDriver.setInviteStatus(CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_WAIT.getCode());
                carrierDriver.setInviteType(CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode());
                carrierDriver.setCreateTime(new Date());
                carrierDriverDomainService.updateCarrierDriverInfo(carrierDriver);
            }
        } else {
            // 不存在数据，则新增数据
            CarrierDriverInfo ncd = new CarrierDriverInfo();
            Date date = new Date();
            ncd.setUserId(command.getUserId());
            ncd.setDriverId(command.getDriverId());
            ncd.setIsDel(YesNoEnum.NAY.getValue());
            ncd.setInviteType(CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode());
            ncd.setInviteStatus(CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_WAIT.getCode());
            ncd.setCreateTime(date);
            ncd.setUpdateTime(date);
            carrierDriverDomainService.createCarrierDriver(ncd);
        }

        return Boolean.TRUE;
    }

    public List<ChiefDTO> searchCarriers(SearchQuery query) {
        List<ChiefDTO> chiefDTOS = new ArrayList<>();

        // 查询车老板列表
        CarrierListQuery carrierListQuery = new CarrierListQuery();
        carrierListQuery.setMobile(query.getMobile());
        carrierListQuery.setAuthenticationStatus(CarrierInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode());
        carrierListQuery.setIdentityType(IdentityTypeEnum.CARRIER_SFLTOP.getSubType());
        carrierListQuery.setCancer(YesNoEnum.NAY.getValue());
        List<CarrierInfo> carrierInfos = carrierInfoDomainService.getCarrierListByParams(carrierListQuery);

        List<Long> carrierIds = carrierInfos.stream().map(CarrierInfo::getId).collect(Collectors.toList());
        // 查询用户信息列表
        List<UserInfoDTO> userInfos = getUserInfo(carrierIds);
        Map<Long, UserInfoDTO> userInfoDTOMap =
            userInfos.stream().collect(Collectors.toMap(UserInfoDTO::getId, Function.identity()));

        // 组装实体
        carrierInfos.forEach(carrierInfo -> {
            UserInfoDTO userInfoDTO = userInfoDTOMap.get(carrierInfo.getCreateUserId());
            ChiefDTO chiefDTO = new ChiefDTO();
            if (ObjectUtil.isNotEmpty(carrierInfo)) {
                chiefDTO.setId(carrierInfo.getId());
                chiefDTO.setMobile(carrierInfo.getMobile());
                chiefDTO.setName(carrierInfo.getName());
            }
            if (ObjectUtil.isNotEmpty(userInfoDTO)) {
                chiefDTO.setHeadUrl(userInfoDTO.getAvatar());
            }
            chiefDTOS.add(chiefDTO);
        });

        return chiefDTOS;
    }

    /**
     * @描述 根据用户集合查询用户基础信息
     * @参数 [carrierIds]
     * @返回值 java.util.List<com.kcwl.euc.interfaces.dto.UserInfoDTO>
     * @创建人 zhl
     * @创建时间 2023/2/7
     * @修改人和其它信息
     */
    private List<UserInfoDTO> getUserInfo(List<Long> carrierIds) {
        UserBaseInfoQuery userBaseInfoQuery = new UserBaseInfoQuery();
        userBaseInfoQuery.setIds(carrierIds);
        ResponseMessage<List<UserInfoDTO>> responseMessage = userBaseService.getByUserIds(userBaseInfoQuery);
        if (responseMessage.isSuccess()) {
            return responseMessage.getResult();
        }
        return Collections.emptyList();
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean driverHandleWaiting(HandleWaitingCommand command) {
        CarrierDriverInfo carrierDriverInfo = carrierDriverDomainService.getById(command.getId());
        if (carrierDriverInfo == null) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (Objects.equals(command.getIsAccept(), YesNoEnum.NAY.getValue())) {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode());
        } else {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode());
        }
        return Boolean.TRUE;
    }

    private void handleCarrierDriver(Long refId, Integer inviteStatus) {
        CarrierDriverInfo updateCd = new CarrierDriverInfo();
        updateCd.setId(refId);
        updateCd.setInviteStatus(inviteStatus);
        updateCd.setUpdateTime(new Date());
        carrierDriverDomainService.updateCarrierDriverInfo(updateCd);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean driverDelCarrier(IdCommand command) {
        // 2、CarrierDriver获取关系，若获取不到，返回错误
        CarrierDriverInfo cd = carrierDriverDomainService.getById(command.getId());
        if (ObjectUtil.isEmpty(cd)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }

        // 3、去carrier_mapping获取得到vehicle_id
        CarrierMappingInfo cm = getCarrierMapping(cd.getUserId(), command.getUserId());

        // 4、若3中获取得到车辆信息，根据司机和车辆获取代收关系，若有代收关系返回错误
        //若无关系，则（1）根据车辆Id修改进行中订单的司机Id为空 （2）逻辑删除carrier_mapping数据 （3）根据车辆Id插入解除司机与车辆关联日志release_driver_log
        if (ObjectUtil.isNotEmpty(cm)) {
            cm.setDriverId(0L);
            carrierMappingDomainService.updateCarrierMapping(cm);
        }

        // 5、逻辑删除CarrierDriver中的关系数据
        handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode());

        return Boolean.TRUE;
    }

    /**
     * 获取车主车辆关系
     *
     * @param carrierId
     * @param driverId
     * @return
     */
    private CarrierMappingInfo getCarrierMapping(Long carrierId, Long driverId) {
        CarrierMappingQuery query = new CarrierMappingQuery();
        query.setDriverId(driverId);
        query.setCarrierId(carrierId);
        List<CarrierMappingInfo> infos = carrierMappingDomainService.queryCarrierMappingInfo(query);
        return !infos.isEmpty() ? infos.get(BigInteger.ZERO.intValue()) : null;
    }

    private void delDriverMapping(Long id) {
        CarrierMappingInfo carrierMapping = new CarrierMappingInfo();
        carrierMapping.setDriverId(NumberUtils.LONG_ZERO);
        carrierMapping.setId(id);
        carrierMappingDomainService.updateCarrierMapping(carrierMapping);
    }

    public Boolean driverRecoverRelation(IdCommand command) {
        // CarrierDriver获取关系，若获取不到，返回错误
        CarrierDriverInfo cd = carrierDriverDomainService.getById(command.getId());
        if (ObjectUtil.isEmpty(cd)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        // 查询车主信息
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(cd.getUserId());
        if (ObjectUtil.isEmpty(carrierInfo) && !Objects.equals(carrierInfo.getIdentityType(),
            IdentityTypeEnum.CARRIER_SFLTOP.getSubType())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.IDENTITYTYPE_FAIL);
        }
        // 如果是车老板解除的，恢复到车老板通过
        if (cd.getInviteStatus() == CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode()) {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode());
        }
        // 如果是司机解除的，恢复到司机通过
        if (cd.getInviteStatus() == CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode()) {
            handleCarrierDriver(command.getId(), CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode());
        }
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean carrierDelDriver(IdCommand command) {
        Long userId = command.getUserId();
        Long id = command.getId();
        //2、CarrierDriver获取关系，若获取不到，返回错误
        CarrierDriverInfo carrierDriverInfo = carrierDriverDomainService.getById(id);
        if (carrierDriverInfo == null) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_DRIVER_NULL);
        }
        //3、去carrier_mapping获取得到vehicle_id
        CarrierMappingInfo carrierMapping = getCarrierMapping(userId, carrierDriverInfo.getDriverId());
        //4、若3中获取得到车辆信息，根据司机和车辆获取代收关系，若有代收关系返回错误
        //若无关系，则（1）根据车辆Id修改进行中订单的司机Id为空 （2）逻辑删除carrier_mapping数据 （3）根据车辆Id插入解除司机与车辆关联日志release_driver_log
        if (null != carrierMapping) {
            delDriverMapping(carrierMapping.getId());
        }
        //5、逻辑删除CarrierDriver中的关系数据
        handleCarrierDriver(id, CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode());
        return Boolean.TRUE;
    }

    public Boolean carrierRecoverRelation(IdCommand command) {
        //2、CarrierDriver获取关系，若获取不到，返回错误
        Long id = command.getId();
        CarrierDriverInfo carrierDriverInfo = carrierDriverDomainService.getById(id);
        if (carrierDriverInfo == null) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_DRIVER_NULL);
        }
        Long driverId = carrierDriverInfo.getDriverId();
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(driverId);
        if (carrierInfo != null && !carrierInfo.getIdentityType()
            .equals(IdentityTypeEnum.CARRIER_DRIVER.getSubType())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_NOT_DRIVER);
        }
        //如果是司机发起申请的，恢复到车老板确认通过状态
        if (carrierDriverInfo.getInviteType().equals(CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode())) {
            handleCarrierDriver(id, CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode());
        }
        //如果是车老板发起邀请的，恢复到司机确认通过状态
        if (carrierDriverInfo.getInviteType().equals(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode())) {
            handleCarrierDriver(id, CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode());
        }
        return Boolean.TRUE;
    }

    public List<ChiefDTO> queryMyCarriers(MyCarriersQuery query) {
        List<ChiefDTO> chiefDTOS = new ArrayList<>();

        // 调整参数
        if (CarrierInviteStatusEnum.PASSED.getCode().equals(query.getInviteStatus())) {
            query.setInviteTypes(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode(),
                CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode()));
            query.setInviteStatusList(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_YES.getCode(),
                CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_YES.getCode()));
        }
        if (CarrierInviteStatusEnum.WAITTING.getCode().equals(query.getInviteStatus())) {
            query.setInviteTypes(
                Collections.singletonList(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode()));
            query.setInviteStatusList(
                Collections.singletonList(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_WAIT.getCode()));
        }
        if (CarrierInviteStatusEnum.UNBINDED.getCode().equals(query.getInviteStatus())) {
            query.setInviteTypes(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteType.CAROWNER.getCode(),
                CarrierInfoEnums.CarrierDriverInviteType.DRIVER.getCode()));
            query.setInviteStatusList(Arrays.asList(CarrierInfoEnums.CarrierDriverInviteStatus.DRIVER_NO.getCode(),
                CarrierInfoEnums.CarrierDriverInviteStatus.CAROWNER_NO.getCode()));
        }

        // 查询车主司机列表
        CarrierDriverQuery driverQuery = new CarrierDriverQuery();
        driverQuery.setDriverId(query.getUserId());
        driverQuery.setInviteTypes(query.getInviteTypes());
        driverQuery.setInviteStatus(query.getInviteStatus());
        List<CarrierDriverInfo> carrierDriverInfos = carrierDriverDomainService.queryCarrierDriver(driverQuery);

        // 获取车主id集合
        List<Long> carrierIds =
            carrierDriverInfos.stream().map(CarrierDriverInfo::getUserId).collect(Collectors.toList());
        // 如果carrierIds为空，直接返回
        if (carrierIds.isEmpty()) {
            return chiefDTOS;
        }

        // 查询车老板列表
        CarrierListQuery carrierListQuery = new CarrierListQuery();
        carrierListQuery.setContent(query.getContent());
        carrierListQuery.setUserIds(carrierIds);
        List<CarrierInfo> carrierInfos = carrierInfoDomainService.getCarrierListByParams(carrierListQuery);
        Map<Long, CarrierInfo> carrierInfoMap =
            carrierInfos.stream().collect(Collectors.toMap(CarrierInfo::getId, Function.identity()));
        List<Long> carrierIdList = carrierInfos.stream().map(CarrierInfo::getId).collect(Collectors.toList());

        // 过滤车主司机信息
        carrierDriverInfos = carrierDriverInfos.stream()
            .filter(carrierDriverInfo -> carrierIdList.contains(carrierDriverInfo.getUserId()))
            .collect(Collectors.toList());

        // 查询用户信息列表
        List<UserInfoDTO> userInfos = getUserInfo(carrierIdList);
        Map<Long, UserInfoDTO> userInfoDTOMap =
            userInfos.stream().collect(Collectors.toMap(UserInfoDTO::getId, Function.identity()));

        // 组装实体
        carrierDriverInfos.forEach(carrierDriverInfo -> {
            CarrierInfo carrierInfo = carrierInfoMap.get(carrierDriverInfo.getUserId());
            UserInfoDTO userInfoDTO = userInfoDTOMap.get(carrierDriverInfo.getUserId());
            ChiefDTO chiefDTO = new ChiefDTO();
            chiefDTO.setCreateTime(DateUtil.formatDateTime(carrierDriverInfo.getCreateTime()));
            chiefDTO.setUpdateTime(DateUtil.formatDateTime(carrierDriverInfo.getUpdateTime()));
            chiefDTO.setInviteType(carrierDriverInfo.getInviteType());
            chiefDTO.setInviteStatus(carrierDriverInfo.getInviteStatus());
            if (ObjectUtil.isNotEmpty(carrierInfo)) {
                chiefDTO.setUserId(carrierInfo.getId());
                chiefDTO.setMobile(carrierInfo.getMobile());
                chiefDTO.setName(carrierInfo.getName());
            }
            if (ObjectUtil.isNotEmpty(userInfoDTO)) {
                chiefDTO.setHeadUrl(userInfoDTO.getAvatar());
            }
            chiefDTOS.add(chiefDTO);
        });

        return chiefDTOS;
    }
}
